/** 任务队列 单例模式 */

import AgentServer from '@/modules/Agent';
import { IFormBusiness } from '@/modules/dao/BusinessDao';
import EventEmeitter from './EventEmeitter';
import { appendToken } from '../../../utils/index';

interface IBusiness {
	name: IBusinessName;
	status: IBusinessStatus;
	clientId: string;
	username: string;
	userRole: string;
	cmdId: number | null;
}

/** 指令枚举 */
enum IBusinessName {
	SCREEN_SHOT = 'screenshot',
	SCREEN_SHARE = 'screenShare',
	SEND_LINK = 'sendLink',
	SEND_VIDEO_LINK = 'sendVideoLink',
	SEND_SCANNER_CODE = 'sendScannerCode',
	CANCEL_SCANNER_CODE = 'cancelScannerCode',
	REQUEST_GEO_LOCATION = 'requestGeoLocation',
	FACE_COMPARE = 'faceCompare',
	SNAP_SHOT = 'snapShot',
	RECORD_SCREEN = 'recordScreen',
	CARD_COMPARE = 'cardCompare',
	SCREEN_MARK = 'screenMark',
	GET_GEO_LOCATION = 'getGeoLocaltion',
	SEND_SIGN = 'sendSign',
	FILL_FORM = 'fillForm',
	SEND_PDF = 'sendPDF',
	SEND_CARD_COLLECTION = 'sendCardCollection',
	SEND_IDCARD_COLLECTION = 'sendIdCardCollection',
	SEND_BANKCARD_COLLECTION = 'sendBankCardCollection',
	SHARED_WHITEDOARD = 'sharedWhiteboard',
	SHARED_PDF = 'sharedPDF',
	SEND_VARIABLE_COLLECTION = 'sendVariableCollection',
	TRANSCRIPT_OF_TESTIMONY = 'transcriptOfTestimony',
	SEND_VIDEO_COLLECTION = 'sendVideoCollection',
	TTS_BROADCAST = 'ttsBroadcast',
	REGIONAL_SCREEN_RECORDING = 'regionalScreenRecording',
	SEND_KNOWLEDGE_BASE = 'sendKnowledgeBase',
	CUSTOMER_VIEW_MARK = 'customerViewMark'
}

enum IBusinessStatus {
	IDLE = 'idle',
	START = 'start',
	IN_PROGRESS = 'in-progress',
	REJECTED = 'rejected',
	CANCEL = 'cancel',
	FAILED = 'failed',
	DONE = 'done',
	ACCEPTED = 'accepted'
}

interface ICompletedProps {
	task: IBusinessName;
	data: IBusiness;
	response: any;
	isRead: boolean;
}

interface IFillForm {
	task: IBusinessName;
	data: IBusiness;
	isRead: boolean;
	response: {
		cmd: IBusinessName;
		data: { followId: string; formId: string; formTemplate: string; formName: string; title: string; detailId?: string }[];
		id: number;
		status: IBusinessStatus;
	};
}

// OCR 结果数据结果
interface OCRResult {
	id: string;
	status: string;
	data: any;
	image: string;
}

const ignoreCompletedTask = [
	IBusinessName.SEND_VIDEO_LINK,
	IBusinessName.SCREEN_MARK,
	IBusinessName.SCREEN_SHARE,
	IBusinessName.SEND_LINK,
	IBusinessName.SEND_PDF,
	// IBusinessName.SEND_VARIABLE_COLLECTION, // 变量采集结果需要及时显示
	IBusinessName.SHARED_PDF,
	IBusinessName.SHARED_WHITEDOARD,
	IBusinessName.SEND_KNOWLEDGE_BASE
];

class BusinessQueneMap extends EventEmeitter {
	private static instance: BusinessQueneMap | null;

	static getInstance(): BusinessQueneMap {
		// 判断系统是否已经有这个单例
		if (BusinessQueneMap.instance === null) {
			BusinessQueneMap.instance = new BusinessQueneMap();
		}
		return BusinessQueneMap.instance; // 单例模式
	}
	private static completedTask: ICompletedProps[] = [];
	public BusinessQuene: Map<string, IBusiness>;
	public BusinessCompletedQuene: Map<string, ICompletedProps> = new Map();
	public BusinessFormQuene: ICompletedProps[] = [];
	public OcrResultList: OCRResult[] = []; // OCR结果数据列表

	constructor() {
		super();
		this.BusinessQuene = new Map();
	}

	public addCompletedTask = async (task: ICompletedProps) => {
		if (ignoreCompletedTask.indexOf(task.data.name) <= -1) {
			console.log('addCompletedTask:', task);
			if (task.data.status === IBusinessStatus.DONE || task.data.status === IBusinessStatus.FAILED) {
				if (task.response?.data?.urls) {
					task.response.data.urls.map((item: any) => {
						item.url = appendToken(item.url);
					});
				} else if (task.response?.imageUrl) {
					task.response.imageUrl = appendToken(task.response.imageUrl);
				} else if (task.response?.data?.url) {
					task.response.data.url = appendToken(task.response.data.url);
					if (task.response.data.pic) {
						task.response.data.pic = appendToken(task.response.data.pic);
					}
				} else if (task.response?.data?.data && typeof task.response.data.data === 'string') {
					task.response.data.data = appendToken(task.response.data.data);
				}
			}
			
			if (task.data.name === IBusinessName.SEND_SIGN) {
				this.BusinessCompletedQuene.set(task.data.username, task);
			} else if (task.data.name === IBusinessName.SEND_SCANNER_CODE) {
				if (task.data.status === IBusinessStatus.DONE) {
					this.BusinessCompletedQuene.set(task.data.username, task);
				}
			} else if (task.data.name === IBusinessName.SEND_IDCARD_COLLECTION) {
				if (task.data.status === IBusinessStatus.DONE) {
					this.BusinessCompletedQuene.set(task.data.username, task);
				}
			} else if (task.data.name === IBusinessName.SEND_BANKCARD_COLLECTION) {
				if (task.data.status === IBusinessStatus.DONE) {
					this.BusinessCompletedQuene.set(task.data.username, task);
				}
			} else if (task.data.name === IBusinessName.TRANSCRIPT_OF_TESTIMONY) {
				if (task.data.status === IBusinessStatus.DONE) {
					this.BusinessCompletedQuene.set(task.data.username, task);
				}
			} else if (task.data.name === IBusinessName.SEND_VIDEO_COLLECTION) {
				if (task.data.status === IBusinessStatus.DONE) {
					this.BusinessCompletedQuene.set(task.data.username, task);
				}
			} else if (task.data.status !== IBusinessStatus.IN_PROGRESS) {
				this.BusinessCompletedQuene.set(task.data.username, task);
			}
		}

		if (task.data.status === 'done' || task.data.status === 'cancel' || task.data.status === 'failed' || task.data.status === 'rejected') {
			if (task.data.name === IBusinessName.FILL_FORM) {
				this.updateFormBusiness(task);
			}

			if (this.hasTask(task.data.clientId)) {
				await this.delTask(task.data.clientId);
			}
		}
	};

	// 删除已完成任务
	public delComletedTask = (clientId: string) => {
		const tasks = [...this.BusinessCompletedQuene.values()];
		tasks.map(item => {
			if (item.data.clientId === clientId) {
				this.BusinessCompletedQuene.delete(item.data.username);
			}
		});
		// 清空OCR识别结果列表
		this.OcrResultList = [];
	};

	public updateComletedTask = (username: string, isRead = false) => {
		if (this.BusinessCompletedQuene.has(username)) {
			const task = this.BusinessCompletedQuene.get(username)!;
			task.isRead = isRead;
			this.BusinessCompletedQuene.set(username, task);
		}
	};

	public getComletedTask = () => {
		const tasks = [...this.BusinessCompletedQuene.values()];
		console.log(tasks);

		return tasks;
	};

	public addTask(key: string, value: IBusiness) {
		return new Promise((resolve, reject) => {
			if (this.hasTask(key)) {
				return Promise.reject({ code: 1001, message: `${key} has early in task` });
			} else {
				this.BusinessQuene.set(key, value);
				this.updateTaskStatus(key, IBusinessStatus.START, null);
				resolve({ code: 200, mesaage: 'success' });
			}
		});
	}

	public hasTask(key: string) {
		return this.BusinessQuene.has(key);
	}

	public delTask(key: string) {
		return new Promise((resolve, reject) => {
			if (!this.hasTask(key)) {
				return Promise.reject({ code: 1002, message: `${key} in task has not found` });
			} else {
				this.BusinessQuene.delete(key);
				resolve({ code: 200, mesaage: 'success' });
			}
		});
	}

	public getTask(key: string) {
		if (!this.hasTask(key)) {
			return null;
		} else {
			return this.getValue(key);
		}
	}

	public updateTaskStatus(key: string, status: IBusinessStatus, cmdId: number | null) {
		return new Promise((resolve, reject) => {
			if (!this.hasTask(key)) {
				reject({ code: 1002, message: `${key} in task has not found` });
			} else {
				this.BusinessQuene.set(key, { ...this.getValue(key), status: status, cmdId: cmdId });
				resolve(this.BusinessQuene.get(key));
				this.emit('business-update', this.BusinessQuene.get(key));
			}
		});
	}

	/** 根据任务名查找任务队列 */
	public findTaskWithTaskName(taskName: IBusinessName) {
		const allTask = [...this.BusinessQuene.values()];
		return allTask.filter(item => item.name === taskName);
	}

	public clearTask() {
		return new Promise((resolve, reject) => {
			this.BusinessQuene.clear();
			resolve({ code: 200, message: 'clear task success' });
		});
	}

	private getValue(key: string) {
		return this.BusinessQuene.get(key)!;
	}

	public getAllTask = () => {
		return this.BusinessQuene;
	};

	public clearCompletedTask = () => {
		this.BusinessCompletedQuene.clear();
		this.BusinessFormQuene = [];
	};

	/** 更新表单队列 */
	public updateFormBusiness = (task: IFillForm) => {
		const formStatus = ['done', 'cancel', 'failed', 'rejected'];
		console.log('updateFormBusiness:', task);

		if (formStatus.indexOf(task.data.status) !== -1) {
			AgentServer.insertFormDetail(task.data.clientId, { forms: task.response.data, clientId: task.data.clientId, status: task.data.status });
			const formTask = this.BusinessFormQuene.find(item => item.data.clientId === task.data.clientId);

			if (formTask) {
				this.BusinessFormQuene.forEach((item, index) => {
					if (item.data.clientId === task.data.clientId && item.response.id === formTask.response.id) {
						this.BusinessFormQuene.splice(index, 1);
						this.BusinessFormQuene = [task, ...this.BusinessFormQuene];
					}
				});
			} else {
				this.BusinessFormQuene = [task, ...this.BusinessFormQuene];
			}
		} else {
			console.log('updateFormBusiness:', this.BusinessFormQuene, task);
		}
	};

	/** 根据 clientId 获取表单队列 */
	public getFormListWithClientId = (clientId: string) => {
		return this.BusinessFormQuene.find(item => item.data.clientId === clientId)?.response;
	};
}

export default BusinessQueneMap;
